﻿using System;
using System.Linq.Expressions;
using CSW.Framework.Common.Binding.Interfaces;
using CSW.Framework.Linq;

namespace CSW.Framework.UI.Binding
{
    /// <summary>
    /// Provides capability to bind controls and error providers to properties in an <see cref="IBindableObject" />.
    /// </summary>
    public class Binder<T> : Binder
        where T : IBindableObject
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Binder"/> class.
        /// </summary>
        /// <param name="bindableObject">The bindable object to bind to.</param>
        /// <param name="errorProvider">The error provider.</param>
        public Binder(T bindableObject, IErrorWrapper errorProvider)
            : this(bindableObject, errorProvider, Binding.ShowErrors.Immediately)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Binder"/> class.
        /// </summary>
        /// <param name="bindableObject">The bindable object to bind to.</param>
        /// <param name="errorProvider">The error provider.</param>
        /// <param name="showErrors">if set to 
        /// <see cref="CSW.Framework.UI.Binding.ShowErrors.AfterSave"/>,
        /// show errors only after save attempted
        /// (default = <see cref="CSW.Framework.UI.Binding.ShowErrors.Immediately"/>).
        /// </param>
        public Binder(T bindableObject, IErrorWrapper errorProvider, ShowErrors showErrors)
            : base(bindableObject, errorProvider, showErrors)
        {
        }

        /// <summary>
        /// Binds a control to a property in the bindable object.
        /// </summary>
        /// <param name="bindableControl">The bindable control.</param>
        /// <param name="property">Expression of the property.</param>
        public virtual string Bind<TResult>(IBindableControl bindableControl, Expression<Func<T, TResult>> property)
        {
            string fieldName = LinqToSqlHelper.GetFieldName(property);
            Bind(bindableControl, fieldName);
            return fieldName;
        }
    }
}
